package com.yanjiali.config.resource;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.util.FileCopyUtils;

import java.io.IOException;
import java.util.Set;

/**
 * @Package: com.yanjiali.com.yanjiali.config.resource
 * @Author: yanjiali
 * @Created: 2024/6/15 10:17
 * 资源服务器配置
 *  主要是配置资源放行路径 和 通过公钥验证jwt
 */
@Slf4j
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .sessionManagement().disable()
                .authorizeRequests().antMatchers(
                        "/v2/api-docs",
                "/swagger-resources/configuration/ui",// 用来获取支持的动作
                "/swagger-resources",// 用来获取 api-docs 的 URI
                "/swagger-resources/configuration/security",// 安全选项
                "/webjars/**",
                "/swagger-ui.html",
                "/v1/login",          //登录接口的放行
                "/v1/chat",
                "/v1/thirdParty/**"
        ).permitAll()
                .antMatchers("/**").authenticated()
                .and().headers().cacheControl();
    }

    /**
     * 配置资源服务器的 token 存储方式为 JWT
     * @param resources
     * @throws Exception
     */
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws
            Exception {
        resources.tokenStore(tokenStore());
    }

    /**
     * 获取 JWT Token Store 类
     * @return TokenStore
     */
    private TokenStore tokenStore() {
        JwtTokenStore jwtTokenStore = new
                JwtTokenStore(jwtAccessTokenConverter());
        return jwtTokenStore;
    }

    /**
     * 定义 JWT AccessToken 转换器，用于验证 token 的公钥
     * @return JwtAccessTokenConverter
     */
    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter tokenConverter = new JwtAccessTokenConverter();
        ClassPathResource classPathResource = new ClassPathResource("tenseek.txt"); //获取对应的公钥文件
        String publicKey = null;
        try {
            byte[] bytes =
                    FileCopyUtils.copyToByteArray(classPathResource.getInputStream());
            publicKey = new String(bytes, "utf-8");
        } catch (IOException e) {
            log.info("读取公钥失败");
        }
        tokenConverter.setVerifierKey(publicKey);
        return tokenConverter;
    }
}
